package com.starleague.battletech.unit.mech.jpa.appengine;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import com.starleague.battletech.unit.ImmutableWeight;
import com.starleague.battletech.unit.jpa.appengine.BattletechUnitComponentGae;
import com.starleague.battletech.unit.mech.IMechActuator;
import com.starleague.battletech.unit.mech.IMechCockpit;
import com.starleague.battletech.unit.mech.IMechLifeSupport;
import com.starleague.battletech.unit.mech.IMechSensors;
import com.starleague.battletech.unit.mech.MechActuatorType;

/**
 * Implementation of Actuator, Cockpit, LifeSupport and Sensor components
 */
@Entity(name = "MECH_CORE_COMPONENT")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class MechCoreComponentGae
        extends BattletechUnitComponentGae
        implements IMechActuator, IMechCockpit, IMechLifeSupport, IMechSensors
{
    public static enum Type
    {
        COCKPIT,
        LIFE_SUPPORT,
        SENSORS
    }

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private MechHitLocationGae hitLocation;

    @Basic(optional = true)
    @Column(nullable = true)
    @Enumerated(EnumType.STRING)
    private MechActuatorType actuatorType;

    @Basic(optional = true)
    @Column(nullable = true)
    @Enumerated(EnumType.STRING)
    private Type coreComponentType;

    @OneToMany(mappedBy = "coreComponent", cascade = CascadeType.ALL)
    private List<MechCoreComponentCriticalSlotGae> criticalSlots;

    MechCoreComponentGae(MechHitLocationGae hitLocation,
                         MechActuatorType actuatorType)
    {
        super(new ImmutableWeight(0.0));
        this.hitLocation = hitLocation;
        this.actuatorType = actuatorType;
        this.criticalSlots = new ArrayList<>();
    }

    MechCoreComponentGae(MechHitLocationGae hitLocation,
                         Type coreComponentType)
    {
        super(new ImmutableWeight(0.0));
        this.hitLocation = hitLocation;
        this.coreComponentType = coreComponentType;
        this.criticalSlots = new ArrayList<>();
    }

    protected MechCoreComponentGae()
    {
        //
    }

    @Override
    public MechHitLocationGae getHitLocation()
    {
        return this.hitLocation;
    }

    @Override
    public MechActuatorType getActuatorType()
    {
        return this.actuatorType;
    }

    public Type getCoreComponentType()
    {
        return this.coreComponentType;
    }

    @Override
    public boolean isHittable()
    {
        return true;
    }

    @Override
    protected List<MechCoreComponentCriticalSlotGae> getCriticalSlots()
    {
        return this.criticalSlots;
    }

    @Override
    public MechGae getMech()
    {
        return this.hitLocation.getMech();
    }

    @Override
    public Map<String, Object> infoProperties()
    {
        Map<String, Object> infoPropertyMap = super.infoProperties();
        infoPropertyMap.put("actuatorType", this.actuatorType);
        infoPropertyMap.put("coreComponentType", this.coreComponentType);
        return infoPropertyMap;
    }
}
